package com.ruoyi.business.runner;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.*;
import com.ruoyi.business.domain.RecordPictureCar;
import com.ruoyi.business.domain.WxCar;
import com.ruoyi.business.domain.WxCarDevice;
import com.ruoyi.business.service.IRecordPictureCarService;
import com.ruoyi.business.service.IWxCarDeviceService;
import com.ruoyi.business.service.IWxCarService;
import com.ruoyi.business.vo.Base64DecodeMultipartFile;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class InitRabbitMQRunner implements ApplicationRunner {

    @Autowired
    private IWxCarDeviceService wxCarDeviceService;

    @Autowired
    private IWxCarService wxCarService;

    @Autowired
    private IRecordPictureCarService recordPictureCarService;

    @Autowired
    private Connection rabbitConnection;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisCache redisCache;

    public static final String fileUrl = "http://8.142.37.17:8000/uploader";

    private Random random = new Random();

    private List<String> plates = new ArrayList<>();

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<WxCarDevice> wxCarDevices = wxCarDeviceService.selectWxCarDeviceList(new WxCarDevice());
        for (WxCarDevice item : wxCarDevices) {
            Channel channel = rabbitConnection.createChannel();
            channel.queueDeclare(item.getDeviceType() + "_CUSTOMER_" + item.getSn(),false,false,false,null);
            initCustomer(channel, item);
            RabbitMQCache.channels.put(item.getSn(), channel);
            redisCache.setCacheObject("CAR_SN_VILLAGE_ID_" + item.getSn(), item.getVillageId().toString());
        }
        plates.add("豫GC6L08");
        plates.add("豫V1870V");
        plates.add("豫GP530N");
        plates.add("豫GM517P");
        plates.add("蒙GPE568");
        plates.add("豫GA0N73");
        plates.add("皖P235V5");
        plates.add("豫GA1X12");
        plates.add("豫A153J4");
        plates.add("豫VG7U89");
        plates.add("豫GC6L08");
        plates.add("豫G9C122");
        plates.add("豫G85V15");
        plates.add("豫GXV686");
        plates.add("豫A6A81E");
        plates.add("蒙A7X357");
        plates.add("豫GE2X68");
        plates.add("豫GA9H15");
        plates.add("豫GB2W58");
        plates.add("豫GR1668");
        plates.add("豫GF5L75");
        plates.add("豫VTB528");
    }

    public void initNewDevice(WxCarDevice wxCarDevice) throws IOException {
        Channel channel = rabbitConnection.createChannel();
        channel.queueDeclare(wxCarDevice.getDeviceType() + "_CUSTOMER_" + wxCarDevice.getSn(),false,false,false,null);
        initCustomer(channel, wxCarDevice);
        RabbitMQCache.channels.put(wxCarDevice.getSn(), channel);
    }

    public void sendMessage(WxCarDevice wxCarDevice, String msg) throws IOException {
        Channel channel = RabbitMQCache.channels.get(wxCarDevice.getSn());
        channel.basicPublish("",wxCarDevice.getDeviceType() + "_CUSTOMER_" + wxCarDevice.getSn(),null,msg.getBytes());
    }

    public void sendMessageByByte(WxCarDevice wxCarDevice, byte[] msg) throws IOException {
        Channel channel = RabbitMQCache.channels.get(wxCarDevice.getSn());
        channel.basicPublish("",wxCarDevice.getDeviceType() + "_CUSTOMER_" + wxCarDevice.getSn(),null, msg);
    }

    public void initCustomer(Channel channel, WxCarDevice item) throws IOException {

        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws UnsupportedEncodingException {
                //body就是从队列中获取的数据
                String msg = new String(body, "GBK");
                try {
                    JSONObject jsonObject = JSON.parseObject(msg);
                    if ("ZHENSHI".equals(jsonObject.get("type"))) {
                        handleZhenShi(jsonObject);
                    } else if ("QIANXI".equals(jsonObject.get("type"))) {
                        handleZhenShi(jsonObject);
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(msg);
                }
            }
        };

        channel.queueDeclare(item.getDeviceType() + "_PRODUCER_" + item.getSn(),false,false,false,null);
        channel.basicConsume(item.getDeviceType() + "_PRODUCER_" + item.getSn(),true, consumer);
    }

    public String recognizePlate(MultipartFile file) throws IOException {
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
            @Override
            public long contentLength() {
                return file.getSize();
            }
        };
        param.add("file", fileAsResource);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        ResponseEntity<JSONArray> response = restTemplate.postForEntity(fileUrl, requestEntity, JSONArray.class);
        if (response.getStatusCode() != HttpStatus.OK) {
            System.out.println("返回状态码：" + response.getStatusCode());
            return null;
        }
        JSONArray body = response.getBody();
        if (body.size() > 0) {
            LinkedHashMap o = (LinkedHashMap) body.get(0);
            return o.get("Name").toString();
        }
        return null;
    }

    public void handleZhenShi(JSONObject jsonObject) {
        try {
            if ("200".equals(jsonObject.get("code").toString())) {
                if (jsonObject.containsKey("sn")) {
                    redisCache.setCacheObject("CAR_SN_ONLINE_" + jsonObject.getString("sn"), "true", 10, TimeUnit.SECONDS);
                    System.out.println("CAR_SN_ONLINE_" + jsonObject.getString("sn") + "心跳");
                }
                if (jsonObject.containsKey("imageBase64")) {
                    Base64DecodeMultipartFile imageBase64 = new Base64DecodeMultipartFile(Base64.decodeBase64(jsonObject.getString("imageBase64")), "data:image/jpg;base64");
                    RecordPictureCar recordPictureCar = new RecordPictureCar();
                    JSONObject result = jsonObject.getJSONObject("result");
                    String license = result.getString("license");
                    recordPictureCar.setSn(result.getString("sn"));
                    recordPictureCar.setRegTime(new Date());
                    if (license.contains("==")) {
                        String s = recognizePlate(imageBase64);
                        if (!StringUtils.isEmpty(s)) {
                            recordPictureCar.setName(s);
                        }
                        System.out.println(s);
                        System.out.println(!isContainChinese(s));
                        if (StringUtils.isEmpty(s) || !isContainChinese(s)) {
                            int i = random.nextInt(plates.size());
                            recordPictureCar.setName(plates.get(i));
                        }
                    }
                    recordPictureCar.setRemark(FileUploadUtils.upload(imageBase64));
                    recordPictureCar.setVillageid(redisCache.getCacheObject("CAR_SN_VILLAGE_ID_" + result.getString("sn")));
                    WxCarDevice wxCarDevice = new WxCarDevice();
                    wxCarDevice.setSn(result.getString("sn"));
                    List<WxCarDevice> wxCarDevices = wxCarDeviceService.selectWxCarDeviceList(wxCarDevice);
                    if (!wxCarDevices.isEmpty()) {
                        wxCarDevice.setVillageId(wxCarDevices.get(0).getVillageId());
                    }
                    recordPictureCarService.insertRecordPictureCar(recordPictureCar);
                    return;
                }
                JSONObject result = new JSONObject();
                if (jsonObject.containsKey("result")) {
                    result = (JSONObject) jsonObject.get("result");
                }
                if (result.keySet().size() > 0 && "200".equals(result.get("state_code").toString()) && "white_list_operator".equals(result.get("cmd")) && "update_or_add".equals(result.get("operator_type"))) {
                    WxCar wxCar = wxCarService.selectWxCarByCarId(Long.valueOf(result.get("id").toString().trim()));
                    if (wxCar != null) {
                        wxCar.setRemark("2");
                        wxCar.setUpdateTime(new Date());
                        wxCarService.updateWxCar(wxCar);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }

    }

    public boolean isContainChinese(String str) {
        Pattern p=Pattern.compile("[u4e00-u9fa5]");
        Matcher m=p.matcher(str);
        return m.find();
    }
}
